﻿using System;
using System.Collections.Generic;
using System.Text;

namespace liuzw.utils
{
    internal static class DateTimeExtensions
    {
        public static int MonthsBetweentwoDates(DateTime startTime, DateTime endTime)
        {
            int yearNum = (endTime.Year - startTime.Year) * 12;
            int monthNum = endTime.Month - startTime.Month;
            int dayNum = endTime.Day - startTime.Day > 0 ? 1 : 0;
            return yearNum + monthNum + dayNum;
        }
        public static string FormatDate(this DateTime dateTime)
        {
            var now = DateTime.Now;
            if (now.Year == dateTime.Year)
            {
                if (now.Date == dateTime.Date)
                {
                    TimeSpan time = now - dateTime;
                    if (time.Hours < 24 && time.Hours >= 1)
                    {

                        return string.Format("{0}小时前", time.Hours);
                    }
                    else if (time.Minutes < 60 && time.Minutes >= 1)
                    {
                        return string.Format("{0}分钟前", time.Minutes);
                    }
                    else if (time.Seconds < 60 && time.Seconds > 0)
                    {
                        return string.Format("{0}秒前", time.Seconds);
                    }
                    else
                    {
                        return "刚刚";
                    }
                }
                else if (now.Date == dateTime.Date.AddDays(1))
                {
                    return string.Format("昨天 {0}", dateTime.ToString("HH:mm"));
                }
                else if (now.Date == dateTime.Date.AddDays(2))
                {
                    return string.Format("前天 {0}", dateTime.ToString("HH:mm"));
                }
                else
                {
                    return string.Format("{0}月{1}日 {2}", dateTime.Month, dateTime.Day, dateTime.ToString("HH:mm"));
                }
            }
            else
            {
                return string.Format("{3}年{0}月{1}日 {2}", dateTime.Month, dateTime.Day, dateTime.ToString("HH:mm"), dateTime.Year);
            }
        }
        public static string FormatDateV2(this DateTime dateTime)
        {
            var now = DateTime.Now;
            if (now.Year == dateTime.Year)
            {
                if (now.Date == dateTime.Date)
                {
                    TimeSpan time = now - dateTime;
                    if (time.Hours < 24 && time.Hours >= 1)
                    {
                        return string.Format("{0}小时前", time.Hours);
                    }
                    else if (time.Minutes < 60 && time.Minutes >= 1)
                    {
                        return string.Format("{0}分钟前", time.Minutes);
                    }
                    else if (time.Seconds < 60 && time.Seconds > 0)
                    {
                        return string.Format("{0}秒前", time.Seconds);
                    }
                    else
                    {
                        return "刚刚";
                    }
                }
                else if (now.Date == dateTime.Date.AddDays(1))
                {
                    return string.Format("昨天 {0}", dateTime.ToString("HH:mm"));
                }
                else if (now.Date == dateTime.Date.AddDays(2))
                {
                    return string.Format("前天 {0}", dateTime.ToString("HH:mm"));
                }
                else
                {
                    return string.Format("{0}月{1}日 {2}", dateTime.Month, dateTime.Day, dateTime.ToString("HH:mm"));
                }
            }
            return string.Format("{0}年{1}月{2}日 ", dateTime.Year, dateTime.Month, dateTime.Day);
        }
        /// <summary>
        /// 移动端时间格式
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string FormatDateV3(this DateTime dateTime)
        {
            var now = DateTime.Now;
            if (now.Year == dateTime.Year)
            {
                if (now.Date == dateTime.Date)
                {
                    return dateTime.ToString("HH:mm");
                }
                else if (now.Date == dateTime.Date.AddDays(1))
                {
                    return string.Format("昨天 {0}", dateTime.ToString("HH:mm"));
                }
                else
                {
                    return dateTime.ToString("MM/dd HH:mm");
                }
            }
            return dateTime.ToString("yyyy/MM/dd");
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatDateCn(this DateTime dateTime)
        {
            return dateTime.ToString("yyyy/MM/dd HH:mm:ss");
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatDateCn(this string dateTime)
        {
            if (string.IsNullOrWhiteSpace(dateTime))
                return null;
            DateTime time;
            DateTime.TryParse(dateTime, out time);
            return time.ToString("yyyy/MM/dd HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatDateCn(this DateTime? dateTime)
        {
            if (dateTime == null || !dateTime.HasValue)
                return "";
            return dateTime.Value.ToString("yyyy/MM/dd HH:mm:ss");
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatShortDate(this DateTime dateTime)
        {
            return dateTime.ToString("yyyy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatShortDate(this string dateTime)
        {
            if (string.IsNullOrWhiteSpace(dateTime))
                return null;
            DateTime time;
            DateTime.TryParse(dateTime, out time);
            return time.ToString("yyyy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
        }
        /// <summary>
        /// 转换日期为指定的格式 yyyy/MM/dd HH:mm:ss
        /// </summary>
        public static string FormatShortDateCn(this DateTime? dateTime)
        {
            if (dateTime == null || !dateTime.HasValue)
                return "";
            return dateTime.Value.ToString("yyyy/MM/dd");
        }
        /// <summary>
        /// 所在周的起止时间
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime[] DatesIncludeDay(this DateTime dateTime)
        {
            DateTime[] dts = new DateTime[2];
            int dayofweek = DayOfIntWeek(dateTime);
            if (dayofweek == 0)
            {
                dts[0] = dateTime.AddDays(-7);
                dts[1] = dateTime.AddDays(6);
            }
            else
            {
                dts[0] = dateTime.AddDays(-dayofweek);
                dts[1] = dateTime.AddDays(6 - dayofweek);
            }
            return dts;
        }
        /// <summary>
        /// 计算星期几，转换为数字
        /// </summary>
        /// <param name="dt">某天的日期</param>
        /// <returns></returns>
        public static int DayOfIntWeek(this DateTime dt)
        {
            string strDayOfWeek = dt.DayOfWeek.ToString().ToLower();
            int intDayOfWeek = 0;
            switch (strDayOfWeek)
            {
                case "monday":
                    intDayOfWeek = 1;
                    break;
                case "tuesday":
                    intDayOfWeek = 2;
                    break;
                case "wednesday":
                    intDayOfWeek = 3;
                    break;
                case "thursday":
                    intDayOfWeek = 4;
                    break;
                case "friday":
                    intDayOfWeek = 5;
                    break;
                case "saturday":
                    intDayOfWeek = 6;
                    break;
                case "sunday":
                    intDayOfWeek = 0;
                    break;
            }
            return intDayOfWeek;
        }
        /// <summary>
        /// 计算星期几，转换为汉字
        /// </summary>
        /// <param name="dt">某天的日期</param>
        /// <returns></returns>
        public static string DayOfChWeek(this DateTime dt)
        {
            var strDayOfWeek = dt.DayOfWeek;
            switch ((int)strDayOfWeek)
            {
                case 1:
                    return "一";
                case 2:
                    return "二";
                case 3:
                    return "三";
                case 4:
                    return "四";
                case 5:
                    return "五";
                case 6:
                    return "六";
                case 0:
                    return "日";
            }
            return string.Empty;
        }
        /// <summary> 
        /// DateTime时间格式转换为Unix时间戳格式 
        /// </summary> 
        /// <param name="time"> DateTime时间格式</param> 
        /// <returns>Unix时间戳格式</returns> 
        public static int ConvertDateTimeInt(this DateTime time)
        {
            DateTime startTime = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
            return (int)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// 获取timestamp（单位毫秒）时间戳
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static long GetTimestamp(this DateTime dateTime)
        {
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return (dateTime.Ticks - dt.Ticks) / 10000;
        }
        /// <summary>
        /// 根据时间戳timestamp（单位毫秒）获取日期
        /// </summary>
        public static DateTime GetDateTime(this long timestamp)
        {
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            long tt = dt.Ticks + timestamp * 10000;
            return new DateTime(tt);
        }
        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式(单位毫秒)
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static long GetTimestampUnix(this DateTime dateTime)
        {
            DateTime dt = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0), TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
            return (dateTime.Ticks - dt.Ticks) / 10000;
        }
        /// <summary>
        /// 根据Unix时间戳timestamp（单位毫秒）获取日期
        /// </summary>
        public static DateTime GetDateTimeUnix(this long timestamp)
        {
            DateTime dt = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0),TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
            long tt = dt.Ticks + timestamp * 10000;
            return new DateTime(tt);
        }
        /// <summary> 
        /// 计算某周礼拜一的日期
        /// </summary> 
        /// <param name="date">该周中任意一天</param> 
        /// <returns>返回礼拜一日期，后面的具体时、分、秒和传入值相等</returns> 
        public static DateTime GetMondayDate(DateTime date)
        {
            int i = date.DayOfWeek - DayOfWeek.Monday;
            if (i == -1) i = 6;// i值 > = 0 ，因为枚举原因，Sunday排在最前，此时Sunday-Monday=-1。 
            TimeSpan ts = new TimeSpan(i, date.Hour, date.Minute, date.Second);
            return date.Subtract(ts);
        }

        /// <summary> 
        /// 计算某日起始日期（礼拜一的日期） 
        /// </summary> 
        /// <param name="currentDate">该周中任意一天</param> 
        /// <returns>返回礼拜一日期，后面的具体时、分、秒和传入值相等</returns> 
        public static DateTime GetMondayDateV2(DateTime currentDate)
        {
            int index = currentDate.DayOfWeek - DayOfWeek.Monday;
            if (index == -1) index = 6;// index值>=0,因为枚举原因，Sunday排在最前，此时Sunday-Monday=-1，必须+7=6。 
            TimeSpan ts = new TimeSpan(index, 0, 0, 0);
            return currentDate.Subtract(ts);
        }
        /// <summary> 
        /// 计算某日结束日期（礼拜日的日期） 
        /// </summary> 
        /// <param name="currentDate">该周中任意一天</param> 
        /// <returns>返回礼拜日日期，后面的具体时、分、秒和传入值相等</returns> 
        public static DateTime GetSundayDate(DateTime currentDate)
        {
            int index = currentDate.DayOfWeek - DayOfWeek.Sunday;
            if (index != 0) index = 7 - index;// 因为枚举原因，Sunday排在最前，相减间隔要被7减。 
            TimeSpan ts = new TimeSpan(index, 0, 0, 0);
            return currentDate.Add(ts);
        }
    }
}
